<cfcomponent output="false" displayName="ixManager" hint="This is the global XI component for the application.">

	<cfset variables.system = "">
	<cfset variables.xi_url = "">
	<cfset variables.content_type = "">
	<cfset variables.service = "">
	<cfset variables.sap_client = "">
	<cfset variables.sap_user = "">
	<cfset variables.sap_password = "">
	<cfset variables.sap_language = "">
	
	<!--- initialization method --->
	<cffunction name="init" access="public" returnType="xiManager" output="false">
		<cfargument name="system" type="string" required="true">
		<cfargument name="xi_url" type="string" required="true">
		<cfargument name="content_type" type="string" required="true">
		<cfargument name="service" type="string" required="true">
		<cfargument name="sap_client" type="string" required="true">
		<cfargument name="sap_user" type="string" required="true">
		<cfargument name="sap_password" type="string" required="true">
		<cfargument name="sap_language" type="string" required="true">
		<cfset variables.system = arguments.system>
		<cfset variables.xi_url = arguments.xi_url>
		<cfset variables.content_type = arguments.xi_url>
		<cfset variables.service = arguments.service>
		<cfset variables.sap_client = arguments.sap_client>
		<cfset variables.sap_user = arguments.sap_user>
		<cfset variables.sap_password = arguments.sap_password>
		<cfset variables.sap_language = arguments.sap_language>
		<cfset variables.loadedAt = now() >
		<cfreturn this>
	</cffunction>


	<!--- http post method --->
	<cffunction name="post_xml" access="public" returntype="any" hint="Used to post XML to XI.">
		<cfargument name="xmldata" type="string" required="yes">
		<cfargument name="xi_namespace" type="string" required="yes">
		<cfargument name="xi_interface" type="string" required="yes">
		<cfset Var full_xi_url="#variables.xi_url#?namespace=#arguments.xi_namespace#&interface=#arguments.xi_interface#&service=#variables.service#&party=&scheme=&sap-client=#variables.sap_client#&sap-user=#variables.sap_user#&sap-password=#variables.sap_password#&sap-language=#variables.sap_language#">
		<cfset Var cfhttp=0 >

		<cfhttp url="#full_xi_url#" method="POST" >
			<cfhttpparam type="HEADER" name="content-type" value="#variables.content_type#">
			<cfhttpparam type="XML" name="xmldata" value="#arguments.xmldata#">
		</cfhttp>
		
		<cfif find( "EXCEPTION_DURING_EXECUTE", cfhttp.FileContent )>
			<cfmail to="weberrors@direct-alliance.com" type="html" from="weberrors@direct-alliance.com" subject="XI XML SAP ERROR ON SEND">
				#full_xi_url#<br /><hr /><br />
				#HTMLCodeFormat(arguments.xmldata)#<br /><hr /><br />
				<cfdump var="#cfhttp#">
			</cfmail>
		</cfif>

		<!--- <cfif application.site_root EQ '/weboe/'>
			<cftry>
				<cftransaction>
					<cfquery name="insertPost" datasource="XI_LOGS"><!--- #request.dsn# --->
						INSERT INTO TBL_XI_POST_LOG( NAMESPACE,INTERFACE,FULL_XI_URL,XML_DATA, DATE_ENTERED )
						VALUES	('#arguments.xi_namespace#','#arguments.xi_interface#','#full_xi_url#','#arguments.xmldata#',#CREATEODBCDATETIME(NOW())#)
					</cfquery>
					<cfquery name="getID" datasource="XI_LOGS">
						SELECT @@IDENTITY as ID
					</cfquery>
				</cftransaction>

				<cfquery name="insertResponse" datasource="XI_LOGS"><!--- #request.dsn# --->
					INSERT INTO TBL_XML_RESPONSE_LOG(XML_RESPONSE,DATE_ENTERED)
					VALUES	('XI_POST_LOG_ID=#getID.id# #cfhttp.filecontent#',#CREATEODBCDATETIME(NOW())#)
				</cfquery>
				<cfcatch type="database"></cfcatch>
			</cftry>
		</cfif> --->

		<cfreturn "#Trim(cfhttp.filecontent)#">
	</cffunction>


	<!--- xi status method --->
	<cffunction name="get_xi_status" access="public" returntype="any" hint="Used to get the XI status.">
		<cfargument name="xmldoc" type="any" required="true">
		<cfargument name="xmldocDetail" type="any" required="true">
			
			<cfscript>
				var xi_status = StructNew();
				xi_status.actioncode=arguments.xmldoc.code;
				xi_status.ActionMessage=arguments.xmldoc.message;
				xi_status.actiontype=arguments.xmldoc.type;
				
				// error code is defined and transaction failed; use error code instead of xmldoc code
				if( isdefined( "arguments.xmldocDetail.xmlChildren" ) ) {
					if(arguments.xmldoc.code NEQ 250 AND ArrayLen(arguments.xmldocDetail.xmlChildren) GTE 1 AND Len(arguments.xmldocDetail.xmlChildren[1].xmlText)){
						xi_status.actioncode = trim(arguments.xmldocDetail.xmlChildren[1].xmlText);
					}
					
					if(arguments.xmldoc.code NEQ 250 AND ArrayLen(arguments.xmldocDetail.xmlChildren) GTE 2 AND Len(arguments.xmldocDetail.xmlChildren[2].xmlText)){
						xi_status.actionmessage = trim(arguments.xmldocDetail.xmlChildren[2].xmlText);
					}
					
					xi_status.actiontype = arguments.xmldoc.type;
				}

				if (xi_status.actioncode EQ 250) {
					xi_status.result = True;
				}
				else {
					xi_status.result = False;
				}
			</cfscript>
		<cfreturn xi_status>
	</cffunction>

	<!--- xml to structure method --->
	<cffunction name="xml_to_struct" access="public" returntype="any" hint="Takes results from XML parser and creates structure of all elements.">
		<cfargument name="xml_data" type="array" default="" required="yes">
		<cfargument name="arraylist" type="string" default="" required="yes"><!--- to have a group of elements returned as array, specify level of the xml in the following format: "shopping_cart.line_item,configuration.component" --->
		<cfargument name="jurisdiction_flag" type="string" default="false" required="yes">
	
		<cfset var tmpstruct = structnew() >
		<cfset var tmpstruct_s = structnew() >
		<cfset var returnvar = structnew() >
		<cfset var toStructReturn = structnew() >
		<cfset var xix = 0 ><!--- Argument.XML_DATA loop index --->
		<cfset var aix = 0 ><!--- Argument.arraylist loop index --->
		<cfset var cix = 0 ><!--- Argument.XML_DATA.children loop index --->
		<cfset var temp = 0 ><!--- Argument.XML_DATA.children loop index --->
		
		<cfif isarray(arguments.xml_data)>
			<cfloop from="1" to="#arraylen(arguments.xml_data)#" index="xix">
		
				<!--- For a complex (nested) xml structure, Recursively call itself to get to the deepest layer --->
				<cfif structkeyexists(arguments.xml_data[xix],"xmlchildren") and arraylen(arguments.xml_data[xix].xmlchildren)>
				
					<cfinvoke component="xiManager" method="xml_to_struct" returnvariable="toStructReturn">
						<cfinvokeargument name="xml_data" value="#arguments.xml_data[xix].xmlchildren#">
						<cfinvokeargument name="arraylist" value="#arguments.arraylist#">
					</cfinvoke>
					<cfset tmpstruct[ arguments.xml_data[xix].XmlName ] = toStructReturn>
						
					<!--- Create any arrays specified in calling list (arraylist parameter) --->
					<cfif len(arguments.arraylist)>
						<cfloop list="#arguments.arraylist#" index="aix">
							<cfif arguments.xml_data[xix].XmlName eq listfirst(aix,".")>
								<cfset "tmpstruct.#listfirst(aix,".")#.#listlast(aix,".")#" = arraynew(1)>
								<!--- go through the number of elements in the MX struct, recursively call xml_to_struct for each element, assign results back to array --->
								<cfloop from="1" to="#arraylen(arguments.xml_data[xix].xmlchildren)#" index="cix">
									<cfif structkeyexists(arguments.xml_data[xix].xmlchildren[cix],"xmlchildren")>
										<cfif findnocase(listlast(aix,"."),arguments.xml_data[xix].xmlchildren[cix].xmlname)>
											<cfif arraylen(arguments.xml_data[xix].xmlchildren[cix].xmlchildren)>
												<cfinvoke component="xiManager" method="xml_to_struct" returnvariable="toStructReturn">
													<cfinvokeargument name="xml_data" value="#arguments.xml_data[xix].xmlchildren[cix].xmlchildren#">
													<cfinvokeargument name="arraylist" value="#arguments.arraylist#">
												</cfinvoke>
											<cfelse>
												<cfset toStructReturn = arguments.xml_data[xix].xmlchildren[cix].xmltext>
											</cfif>
											<cfset arrayappend(evaluate("tmpstruct." & listfirst(aix,".") & "." & listlast(aix,".")),toStructReturn)>
										</cfif>
									</cfif>
								</cfloop>
							</cfif>
						</cfloop>
					</cfif>
					
				<cfelse>
					<cfset tmpstruct[ arguments.xml_data[xix].XmlName ] = arguments.xml_data[xix].xmltext>
				</cfif>
			</cfloop>
			<cfset returnvar = tmpstruct>
		</cfif>
		<cfreturn returnvar >
	</cffunction>


	<!--- process xml method --->
	<cffunction name="process_xml" access="public" returntype="any" hint="Used to process the XI XML.">
		<cfargument name="xml_response" type="string" required="yes">
		<cfargument name="parse_type" type="string" required="yes">
		<cfargument name="arraylist" type="string" required="no" default="">

		<cfset Var xmldoc_in = "">
		<cfset Var xmldoc = "">
		<cfset Var xi_status = "">
		<cfset Var tmpstruct = structnew()>
		<cfset Var KeyArray = ArrayNew(1)>

		<cftry>
			<cfset xmldoc_in=XmlParse(Trim(arguments.xml_response))>
			<cfcatch>
				<cfset xmldoc='<xtioutput>
					<outputheader>
						<actionset>
							<action type="result" message="Critical System Error" code="911.911"></action>
							<msg>
								<error_code>911.911</error_code>
								<message>Critical System Error</message>
							</msg>
						</actionset>
					</outputheader>
					<outputdata>
						<system_response><![CDATA[#Trim(arguments.xml_response)#]]></system_response>
					</outputdata>
				</xtioutput>'>
				<cfset xmldoc_in=XmlParse(xmldoc)>
			</cfcatch>
		</cftry>
		
		<!--- parse the status --->
		<cfif ArrayLen( xmldoc_in.xtioutput.outputheader.XmlChildren[1].XmlChildren ) GTE 2 >
			<cfset xi_status = get_xi_status(xmldoc_in.xtioutput.outputheader.XmlChildren[1].XmlChildren[1].XmlAttributes,xmldoc_in.xtioutput.outputheader.XmlChildren[1].XmlChildren[2])>
		<cfelse>
			<cfset xi_status = get_xi_status(xmldoc_in.xtioutput.outputheader.XmlChildren[1].XmlChildren[1].XmlAttributes,"")>
		</cfif>
		
		<!--- Convert the xml to CF variables --->
		
		<cfif (xi_status.result and xi_status.actioncode eq 250)>
		
			<cfswitch expression="#arguments.parse_type#">
				<cfcase value="1">
					<cfset KeyArray=StructKeyArray(xmldoc_in)>
					<cfset get_wrapper_struct=evaluate("xmldoc_in." & KeyArray[1])>
					<cfset tmpstruct = xml_to_struct( get_wrapper_struct, arguments.arraylist )>
				</cfcase>
				<cfcase value="2">
					<cfset tmpstruct = xml_to_struct( xmldoc_in.xtioutput.outputdata.xmlchildren, arguments.arraylist )>
				</cfcase>
				<cfcase value="3"><!--- ONLY USED FOR CHG_ORDER --->
					<cfset tmpstruct_s = xml_to_struct( xmldoc_in.xtioutput.outputdata.xmlchildren[1].XmlChildren, arguments.arraylist )>
					<cfset tmpstruct = xml_to_struct( xmldoc_in.xtioutput.outputdata.xmlchildren[2].XmlChildren, arguments.arraylist )>
					<cfoutput><cfloop collection="#tmpstruct_s#" item="i"><cfset "tmpstruct.#i#"=Evaluate('tmpstruct_s.'&i)></cfloop></cfoutput>
				</cfcase>
				<cfdefaultcase>
					<cfset tmpstruct = xml_to_struct( xmldoc_in.xtioutput.outputdata.xmlchildren, arguments.arraylist )>
				</cfdefaultcase>
			</cfswitch>
		</cfif>
		<cfset tmpstruct.result = 'true'>
		
		<!--- Return the variables to the calling page --->
		<cfscript>
			tmpstruct.actiontype = xi_status.actiontype;
			tmpstruct.actioncode = xi_status.actioncode;
			tmpstruct.actionmessage = xi_status.actionmessage;
		</cfscript>
	
		<cfreturn tmpstruct>
	</cffunction>


	<!--- xi execution method --->
	<cffunction name="execute_xi" access="public" returntype="any" hint="Used to execute the XI process.">
		<cfargument name="post" type="string" required="yes">
		<cfargument name="parse_type" type="string" default="" required="yes">
		<cfargument name="arraylist" type="string" required="no" default="">
		<cfscript>
			Var xml='';
			Var xml_response='';
			Var xi_response='';
			Var xi_namespace='';
			Var xi_interface='';
		</cfscript>
		<cfinclude template="#trim(arguments.post)#.cfm">
		<cfset xml_response=post_xml(xmldata="#xml#",xi_namespace="#xi_namespace#",xi_interface="#xi_interface#")>
		<cfset xi_response=process_xml(xml_response="#xml_response#",parse_type="#arguments.parse_type#",arraylist="#arguments.arraylist#")>
		<cfset xi_response["xml_response"] = xml_response>
		<cfsetting enablecfoutputonly="No">
		<cfreturn xi_response>
	</cffunction>


</cfcomponent>